package com.brainwave.data;

import android.content.Context;
import androidx.room.Room;
import androidx.room.Database;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import androidx.room.Dao;
import androidx.room.Query;
import androidx.room.Insert;
import androidx.room.Update;
import androidx.room.Delete;

import com.brainwave.models.BrainWaveData;
import com.brainwave.utils.DateConverter;

import java.util.List;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.schedulers.Schedulers;
import io.reactivex.rxjava3.subjects.PublishSubject;

/**
 * 数据仓库类
 * 负责脑波数据的本地存储、查询和云端同步
 * 使用Room数据库进行本地存储
 */
public class DataRepository {
    
    private static final String TAG = "DataRepository";
    private static final String DATABASE_NAME = "brainwave_database";
    
    // 单例实例
    private static volatile DataRepository INSTANCE;
    
    // 数据库和DAO
    private final BrainWaveDatabase database;
    private final BrainWaveDao brainWaveDao;
    
    // 线程池
    private final ExecutorService executorService;
    
    // 数据变化通知
    private final PublishSubject<String> dataChangeSubject;
    
    /**
     * Room数据库定义
     */
    @Database(
        entities = {BrainWaveData.class},
        version = 1,
        exportSchema = false
    )
    @TypeConverters({DateConverter.class})
    public abstract static class BrainWaveDatabase extends RoomDatabase {
        public abstract BrainWaveDao brainWaveDao();
    }
    
    /**
     * Room DAO接口
     */
    @Dao
    public interface BrainWaveDao {
        
        @Query("SELECT * FROM brainwave_data ORDER BY timestamp DESC")
        List<BrainWaveData> getAllData();
        
        @Query("SELECT * FROM brainwave_data WHERE sessionId = :sessionId ORDER BY timestamp ASC")
        List<BrainWaveData> getDataBySession(String sessionId);
        
        @Query("SELECT * FROM brainwave_data WHERE timestamp BETWEEN :startTime AND :endTime ORDER BY timestamp ASC")
        List<BrainWaveData> getDataByTimeRange(long startTime, long endTime);
        
        @Query("SELECT * FROM brainwave_data WHERE recordTime BETWEEN :startDate AND :endDate ORDER BY timestamp ASC")
        List<BrainWaveData> getDataByDateRange(Date startDate, Date endDate);
        
        @Query("SELECT * FROM brainwave_data WHERE isValid = 1 ORDER BY timestamp DESC LIMIT :limit")
        List<BrainWaveData> getValidData(int limit);
        
        @Query("SELECT * FROM brainwave_data WHERE poorSignal < :threshold ORDER BY timestamp DESC")
        List<BrainWaveData> getGoodQualityData(int threshold);
        
        @Query("SELECT DISTINCT sessionId FROM brainwave_data ORDER BY timestamp DESC")
        List<String> getAllSessionIds();
        
        @Query("SELECT COUNT(*) FROM brainwave_data")
        int getTotalCount();
        
        @Query("SELECT COUNT(*) FROM brainwave_data WHERE sessionId = :sessionId")
        int getSessionDataCount(String sessionId);
        
        @Query("SELECT COUNT(*) FROM brainwave_data WHERE isValid = 1")
        int getValidDataCount();
        
        @Query("SELECT AVG(attention) FROM brainwave_data WHERE sessionId = :sessionId AND isValid = 1")
        double getAverageAttention(String sessionId);
        
        @Query("SELECT AVG(meditation) FROM brainwave_data WHERE sessionId = :sessionId AND isValid = 1")
        double getAverageMeditation(String sessionId);
        
        @Query("SELECT * FROM brainwave_data ORDER BY timestamp DESC LIMIT 1")
        BrainWaveData getLatestData();
        
        @Query("DELETE FROM brainwave_data WHERE timestamp < :cutoffTime")
        int deleteOldData(long cutoffTime);
        
        @Query("DELETE FROM brainwave_data WHERE sessionId = :sessionId")
        int deleteSessionData(String sessionId);
        
        @Insert
        long insertData(BrainWaveData data);
        
        @Insert
        List<Long> insertDataList(List<BrainWaveData> dataList);
        
        @Update
        int updateData(BrainWaveData data);
        
        @Delete
        int deleteData(BrainWaveData data);
    }
    
    /**
     * 私有构造函数
     */
    private DataRepository(Context context) {
        // 创建数据库
        database = Room.databaseBuilder(
            context.getApplicationContext(),
            BrainWaveDatabase.class,
            DATABASE_NAME
        ).build();
        
        brainWaveDao = database.brainWaveDao();
        executorService = Executors.newFixedThreadPool(3);
        dataChangeSubject = PublishSubject.create();
    }
    
    /**
     * 获取单例实例
     */
    public static DataRepository getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (DataRepository.class) {
                if (INSTANCE == null) {
                    INSTANCE = new DataRepository(context);
                }
            }
        }
        return INSTANCE;
    }
    
    /**
     * 插入单条数据
     */
    public Single<Long> insertData(BrainWaveData data) {
        return Single.fromCallable(() -> {
            long id = brainWaveDao.insertData(data);
            dataChangeSubject.onNext("INSERT");
            return id;
        }).subscribeOn(Schedulers.io());
    }
    
    /**
     * 批量插入数据
     */
    public Single<List<Long>> insertDataList(List<BrainWaveData> dataList) {
        return Single.fromCallable(() -> {
            List<Long> ids = brainWaveDao.insertDataList(dataList);
            dataChangeSubject.onNext("BATCH_INSERT");
            return ids;
        }).subscribeOn(Schedulers.io());
    }
    
    /**
     * 更新数据
     */
    public Single<Integer> updateData(BrainWaveData data) {
        return Single.fromCallable(() -> {
            int count = brainWaveDao.updateData(data);
            dataChangeSubject.onNext("UPDATE");
            return count;
        }).subscribeOn(Schedulers.io());
    }
    
    /**
     * 删除数据
     */
    public Single<Integer> deleteData(BrainWaveData data) {
        return Single.fromCallable(() -> {
            int count = brainWaveDao.deleteData(data);
            dataChangeSubject.onNext("DELETE");
            return count;
        }).subscribeOn(Schedulers.io());
    }
    
    /**
     * 获取所有数据
     */
    public Single<List<BrainWaveData>> getAllData() {
        return Single.fromCallable(() -> brainWaveDao.getAllData())
            .subscribeOn(Schedulers.io());
    }
    
    /**
     * 根据会话ID获取数据
     */
    public Single<List<BrainWaveData>> getDataBySession(String sessionId) {
        return Single.fromCallable(() -> brainWaveDao.getDataBySession(sessionId))
            .subscribeOn(Schedulers.io());
    }
    
    /**
     * 根据时间范围获取数据
     */
    public Single<List<BrainWaveData>> getDataByTimeRange(long startTime, long endTime) {
        return Single.fromCallable(() -> brainWaveDao.getDataByTimeRange(startTime, endTime))
            .subscribeOn(Schedulers.io());
    }
    
    /**
     * 根据日期范围获取数据
     */
    public Single<List<BrainWaveData>> getDataByDateRange(Date startDate, Date endDate) {
        return Single.fromCallable(() -> brainWaveDao.getDataByDateRange(startDate, endDate))
            .subscribeOn(Schedulers.io());
    }
    
    /**
     * 获取有效数据
     */
    public Single<List<BrainWaveData>> getValidData(int limit) {
        return Single.fromCallable(() -> brainWaveDao.getValidData(limit))
            .subscribeOn(Schedulers.io());
    }
    
    /**
     * 获取高质量数据
     */
    public Single<List<BrainWaveData>> getGoodQualityData(int threshold) {
        return Single.fromCallable(() -> brainWaveDao.getGoodQualityData(threshold))
            .subscribeOn(Schedulers.io());
    }
    
    /**
     * 获取所有会话ID
     */
    public Single<List<String>> getAllSessionIds() {
        return Single.fromCallable(() -> brainWaveDao.getAllSessionIds())
            .subscribeOn(Schedulers.io());
    }
    
    /**
     * 获取最新数据
     */
    public Single<BrainWaveData> getLatestData() {
        return Single.fromCallable(() -> brainWaveDao.getLatestData())
            .subscribeOn(Schedulers.io());
    }
    
    /**
     * 获取数据统计信息
     */
    public Single<DataStatistics> getDataStatistics() {
        return Single.fromCallable(() -> {
            int totalCount = brainWaveDao.getTotalCount();
            int validCount = brainWaveDao.getValidDataCount();
            List<String> sessionIds = brainWaveDao.getAllSessionIds();
            
            return new DataStatistics(totalCount, validCount, sessionIds.size());
        }).subscribeOn(Schedulers.io());
    }
    
    /**
     * 获取会话统计信息
     */
    public Single<SessionStatistics> getSessionStatistics(String sessionId) {
        return Single.fromCallable(() -> {
            int dataCount = brainWaveDao.getSessionDataCount(sessionId);
            double avgAttention = brainWaveDao.getAverageAttention(sessionId);
            double avgMeditation = brainWaveDao.getAverageMeditation(sessionId);
            
            return new SessionStatistics(sessionId, dataCount, avgAttention, avgMeditation);
        }).subscribeOn(Schedulers.io());
    }
    
    /**
     * 删除旧数据
     */
    public Single<Integer> deleteOldData(long cutoffTime) {
        return Single.fromCallable(() -> {
            int count = brainWaveDao.deleteOldData(cutoffTime);
            dataChangeSubject.onNext("DELETE_OLD");
            return count;
        }).subscribeOn(Schedulers.io());
    }
    
    /**
     * 删除会话数据
     */
    public Single<Integer> deleteSessionData(String sessionId) {
        return Single.fromCallable(() -> {
            int count = brainWaveDao.deleteSessionData(sessionId);
            dataChangeSubject.onNext("DELETE_SESSION");
            return count;
        }).subscribeOn(Schedulers.io());
    }
    
    /**
     * 获取数据变化通知流
     */
    public Observable<String> getDataChangeStream() {
        return dataChangeSubject.asObservable();
    }
    
    /**
     * 数据统计信息类
     */
    public static class DataStatistics {
        public final int totalCount;
        public final int validCount;
        public final int sessionCount;
        public final double validRate;
        
        public DataStatistics(int totalCount, int validCount, int sessionCount) {
            this.totalCount = totalCount;
            this.validCount = validCount;
            this.sessionCount = sessionCount;
            this.validRate = totalCount > 0 ? (double) validCount / totalCount * 100 : 0;
        }
        
        @Override
        public String toString() {
            return String.format("总数据: %d, 有效数据: %d (%.1f%%), 会话数: %d",
                totalCount, validCount, validRate, sessionCount);
        }
    }
    
    /**
     * 会话统计信息类
     */
    public static class SessionStatistics {
        public final String sessionId;
        public final int dataCount;
        public final double averageAttention;
        public final double averageMeditation;
        
        public SessionStatistics(String sessionId, int dataCount, 
                               double averageAttention, double averageMeditation) {
            this.sessionId = sessionId;
            this.dataCount = dataCount;
            this.averageAttention = averageAttention;
            this.averageMeditation = averageMeditation;
        }
        
        @Override
        public String toString() {
            return String.format("会话 %s: 数据量 %d, 平均注意力 %.1f, 平均冥想 %.1f",
                sessionId, dataCount, averageAttention, averageMeditation);
        }
    }
    
    /**
     * 数据导出功能
     */
    public Single<String> exportDataToJson(String sessionId) {
        return getDataBySession(sessionId)
            .map(dataList -> {
                // 这里可以使用Gson将数据转换为JSON
                // 为了简化，这里返回一个简单的字符串表示
                StringBuilder json = new StringBuilder();
                json.append("{\n");
                json.append("  \"sessionId\": \"").append(sessionId).append("\",\n");
                json.append("  \"dataCount\": ").append(dataList.size()).append(",\n");
                json.append("  \"data\": [\n");
                
                for (int i = 0; i < dataList.size(); i++) {
                    BrainWaveData data = dataList.get(i);
                    json.append("    {\n");
                    json.append("      \"timestamp\": ").append(data.getTimestamp()).append(",\n");
                    json.append("      \"attention\": ").append(data.getAttention()).append(",\n");
                    json.append("      \"meditation\": ").append(data.getMeditation()).append(",\n");
                    json.append("      \"poorSignal\": ").append(data.getPoorSignal()).append("\n");
                    json.append("    }");
                    if (i < dataList.size() - 1) {
                        json.append(",");
                    }
                    json.append("\n");
                }
                
                json.append("  ]\n");
                json.append("}");
                
                return json.toString();
            });
    }
    
    /**
     * 数据备份功能
     */
    public Single<Boolean> backupData() {
        return getAllData()
            .map(dataList -> {
                // 这里可以实现数据备份逻辑
                // 例如保存到外部存储或云端
                return !dataList.isEmpty();
            });
    }
    
    /**
     * 数据恢复功能
     */
    public Single<Integer> restoreData(List<BrainWaveData> dataList) {
        return insertDataList(dataList)
            .map(List::size);
    }
    
    /**
     * 清理资源
     */
    public void cleanup() {
        if (executorService != null && !executorService.isShutdown()) {
            executorService.shutdown();
        }
        
        if (database != null && database.isOpen()) {
            database.close();
        }
        
        dataChangeSubject.onComplete();
    }
}